package net.xdclass.util;

import com.jayway.jsonpath.JsonPath;
import io.restassured.response.Response;
import net.xdclass.dto.api.ApiJsonRelationDTO;
import net.xdclass.enums.ApiRelateFieldFromEnum;
import net.xdclass.enums.ApiRelateTypeEnum;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.service.api.core.ApiRequest;

import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ApiRelationSaveUtil {

    public static void dispatcher(ApiRequest request, Response response) {
        if (Objects.isNull(request.getRelation())) {
            return;
        }

        List<ApiJsonRelationDTO> relationList = request.getRelationList();

        for(ApiJsonRelationDTO relation : relationList) {
            ApiRelateTypeEnum relateTypeEnum = ApiRelateTypeEnum.valueOf(relation.getType());
            switch (relateTypeEnum) {
                case REGEXP -> {
                    regexp(request, response, relation);
                }
                case JSONPATH -> {
                    jsonpath(request, response, relation);
                }
                default -> {
                    throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_FROM);
                }
            }
        }
    }

    /**
     * 关联取值 JSONPATH
     * @param request 请求对象
     * @param response 响应对象
     * @param relation
     */
    public static void jsonpath(ApiRequest request, Response response, ApiJsonRelationDTO relation) {
        try {
            ApiRelateFieldFromEnum fieldFromEnum = ApiRelateFieldFromEnum.valueOf(relation.getFrom());
            String value = switch (fieldFromEnum) {
                case REQUEST_HEADER -> request.getHeader();
                case REQUEST_BODY -> request.getRequestBody().getBody();
                case REQUEST_QUERY -> request.getQuery();
                case RESPONSE_HEADER -> JsonUtil.obj2Json(response.getHeaders());
                case RESPONSE_DATA -> response.getBody().asString();
                default -> throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_FROM);
            };

            Object json = JsonPath.read(value , relation.getExpress());
            if (json != null) {
                ApiRelationContext.set(relation.getName(), String.valueOf(json));
            }
        } catch (Exception e) {
            throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_RELATION,e);
        }
    }

    /**
     * 关联取值 REGEXP
     * @param request 请求对象
     * @param response 响应对象
     * @param relation
     */
    public static void regexp(ApiRequest request, Response response, ApiJsonRelationDTO relation) {
        try {
            Pattern pattern = Pattern.compile(relation.getExpress());
            ApiRelateFieldFromEnum fieldFromEnum = ApiRelateFieldFromEnum.valueOf(relation.getFrom());
            String value = switch (fieldFromEnum) {
                case REQUEST_HEADER -> request.getHeader();
                case REQUEST_BODY -> request.getRequestBody().getBody();
                case REQUEST_QUERY -> request.getQuery();
                case RESPONSE_HEADER -> response.getHeaders().toString();
                case RESPONSE_DATA -> response.getBody().toString();
                default -> throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_FROM);
            };
            Matcher matcher = pattern.matcher(value);
            if (matcher.find()) {
                ApiRelationContext.set(relation.getName(), matcher.group());
            }
        } catch (Exception e) {
            throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_RELATION,e);
        }
    }
}
